from flask_login import UserMixin
from werkzeug.security import check_password_hash, generate_password_hash
from datetime import datetime
from app.utils.log_config import get_logger
from app.models.base import Model
from app.models.db import get_db

# 配置日志
logger = get_logger('user_model')

# 用户类（继承自Model基类和UserMixin）
class User(Model, UserMixin):
    # 表名
    table_name = "users"
    # 主键
    primary_key = "id"
    
    def __init__(self, id=None, username=None, role=None, password=None, last_login=None):
        super().__init__(id=id, username=username, role=role, password=password, last_login=last_login)
        self.role = role  # 角色：'admin' 或 'operator'
        self.password = password  # 存储密码哈希值
    
    # 检查密码（对比加密后的哈希值）
    def check_password(self, password):
        try:
            # 直接使用实例的password字段（已哈希）
            if hasattr(self, 'password') and self.password:
                return check_password_hash(self.password, password)
            return False
        except Exception as e:
            logger.error(f"密码验证失败: {e}")
            return False
    
    def set_password(self, password):
        """设置新密码（使用哈希）"""
        self.password = generate_password_hash(password)
        return True
    
    def save(self):
        """保存用户信息"""
        try:
            # 使用Model基类的save方法
            result = super().save()
            if result:
                logger.info(f'用户 {self.username} 信息已更新')
            return result
        except Exception as e:
            logger.error(f'更新用户 {self.username} 信息时出错: {str(e)}')
            return False

    def update_login_time(self):
        """更新登录时间"""
        try:
            self.last_login = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            result = self.save()
            if result:
                logger.info(f'用户 {self.username} 登录时间已更新')
            return result
        except Exception as e:
            logger.error(f'更新用户 {self.username} 登录时间时出错: {str(e)}')
            return False
    
    # 从元组创建实例（必需实现）
    @classmethod
    def _tuple_to_instance(cls, row: tuple) -> 'User':
        return cls(
            id=row[0],
            username=row[1],
            role=row[2] if len(row) > 2 else None,
            password=row[3] if len(row) > 3 else None,
            last_login=row[4] if len(row) > 4 else None
        )
    
    # Flask-Login所需的方法
    def get_id(self):
        return str(self.id)
    
    @property
    def is_active(self):
        return True  # 简化实现，所有用户都视为活跃
    
    @property
    def is_authenticated(self):
        return True  # 简化实现
    
    @property
    def is_anonymous(self):
        return False

# 根据ID加载用户（Flask-Login必需）
def load_user(user_id):
    db = get_db()
    cursor = db.cursor()
    cursor.execute("SELECT id, username, role, password FROM users WHERE id=?", (user_id,))
    user_data = cursor.fetchone()
    if not user_data:
        return None
    # 使用元组索引访问，因为返回的是sqlite3.Row对象
    return User(
        id=user_data[0],
        username=user_data[1],
        role=user_data[2],
        password=user_data[3] if len(user_data) > 3 else None
    )

# 根据用户名查询用户
def get_user_by_username(username):
    db = get_db()
    cursor = db.cursor()
    cursor.execute("SELECT id, username, role, password FROM users WHERE username=?", (username,))
    user_data = cursor.fetchone()
    if not user_data:
        return None
    # 使用元组索引访问，因为返回的是sqlite3.Row对象
    return User(
        id=user_data[0],
        username=user_data[1],
        role=user_data[2],
        password=user_data[3] if len(user_data) > 3 else None
    )

# 更新用户最后登录时间
def update_last_login(user_id):
    db = get_db()
    cursor = db.cursor()
    cursor.execute("UPDATE users SET last_login=? WHERE id=?", 
                  (datetime.now().strftime('%Y-%m-%d %H:%M:%S'), user_id))
    db.commit()

# 创建新用户
def create_user(username, password, role='operator'):
    """创建新用户，使用密码哈希"""
    try:
        db = get_db()
        cursor = db.cursor()
        
        # 检查用户名是否已存在
        cursor.execute("SELECT id FROM users WHERE username = ?", (username,))
        if cursor.fetchone():
            logger.warning(f'尝试创建重复用户: {username}')
            return None
        
        # 创建带哈希密码的新用户
        hashed_password = generate_password_hash(password)
        now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        
        cursor.execute(
            "INSERT INTO users (username, password, role, created_at) VALUES (?, ?, ?, ?)",
            (username, hashed_password, role, now)
        )
        db.commit()
        
        # 返回新创建的用户
        user_id = cursor.lastrowid
        logger.info(f'创建新用户成功: {username} (ID: {user_id})')
        return User(user_id, username, role, hashed_password)
    except Exception as e:
        logger.error(f'创建用户 {username} 时出错: {str(e)}')
        db.rollback()
        return None